"""评估过程的辅助函数。"""

import json
import os
from datetime import datetime
from typing import (
    Any,
    Dict,
    List,
    Optional,
    Tuple,
    Union,
)

from langfuse.api.resources.commons.types.trace_with_details import TraceWithDetails

from app.core.logging import logger
from evals.schemas import ScoreSchema


def format_messages(messages: list[dict]) -> str:
    """格式化消息列表以供评估。

    Args:
        messages: 消息字典列表。

    Returns:
        格式化消息的字符串表示。
    """
    formatted_messages = []
    for idx, message in enumerate(messages):
        if message["type"] == "tool":
            formatted_messages.append(
                f"tool {message.get('name')} input: {messages[idx - 1].get('additional_kwargs', {}).get('tool_calls', [])[0].get('function', {}).get('arguments')} {message.get('content')[:100]}..."
                if len(message.get("content", "")) > 100
                else f"tool {message.get('name')}: {message.get('content')}"
            )
        elif message["content"]:
            formatted_messages.append(f"{message['type']}: {message['content']}")
    return "\n".join(formatted_messages)


def get_input_output(trace: TraceWithDetails) -> Tuple[Optional[str], Optional[str]]:
    """从轨迹中提取和格式化输入和输出消息。

    Args:
        trace: 要从中提取消息的轨迹。

    Returns:
        (formatted_input, formatted_output) 的元组。如果输出不是字典则为 None。
    """
    if not isinstance(trace.output, dict):
        return None, None
    input_messages = trace.output.get("messages", [])[:-1]
    output_message = trace.output.get("messages", [])[-1]
    return format_messages(input_messages), format_messages([output_message])


def initialize_report() -> Dict[str, Any]:
    """初始化报告数据结构。

    Returns:
        初始化的报告字典。
    """
    return {
        "timestamp": datetime.now().isoformat(),
        "model": model_name,
        "total_traces": 0,
        "successful_traces": 0,
        "failed_traces": 0,
        "duration_seconds": 0,
        "metrics_summary": {},
        "successful_traces_details": [],
        "failed_traces_details": [],
    }


def initialize_metrics_summary() -> Dict[str, Any]:
    """初始化指标摘要数据结构。

    Returns:
        初始化的指标摘要字典。
    """
    return {}


def process_trace_results(
    result: Dict[str, Any], report: Dict[str, Any], metrics_summary: Dict[str, Any], success_count: int
) -> int:
    """处理轨迹评估结果。

    Args:
        result: 轨迹评估结果。
        report: 报告数据结构。
        metrics_summary: 指标摘要数据结构。
        success_count: 当前成功计数。

    Returns:
        更新后的成功计数。
    """
    if result["success"]:
        success_count += 1
        report["successful_traces"] += 1
        report["successful_traces_details"].append(
            {"trace_id": result["trace_id"], "metrics_results": result["metrics_results"]}
        )
    else:
        report["failed_traces"] += 1
        report["failed_traces_details"].append(
            {
                "trace_id": result["trace_id"],
                "metrics_evaluated": result["metrics_evaluated"],
                "metrics_succeeded": result["metrics_succeeded"],
                "metrics_results": result["metrics_results"],
            }
        )
    return success_count


def update_success_metrics(result: Dict[str, Any], metrics_summary: Dict[str, Any]) -> None:
    """更新成功轨迹的指标。

    Args:
        result: 轨迹评估结果。
        metrics_summary: 指标摘要数据结构。
    """
    for metric_name, score in result["metrics_results"].items():
        if score["success"]:
            metrics_summary[metric_name]["success_count"] += 1
            metrics_summary[metric_name]["avg_score"] += score["score"]


def update_failure_metrics(metrics_summary: Dict[str, Any]) -> None:
    """更新失败轨迹的指标。

    Args:
        metrics_summary: 指标摘要数据结构。
    """
    for metric_name in metrics_summary:
        metrics_summary[metric_name]["failure_count"] += 1


def calculate_avg_scores(report: Dict[str, Any], metrics_summary: Dict[str, Any]) -> None:
    """计算平均分数。

    Args:
        report: 报告数据结构。
        metrics_summary: 指标摘要数据结构。
    """
    for metric_name, data in metrics_summary.items():
        if data["success_count"] > 0:
            data["avg_score"] = round(data["avg_score"] / data["success_count"], 2)


def generate_report(report: Dict[str, Any], metrics_summary: Dict[str, Any], duration: float) -> str:
    """生成评估报告。

    Args:
        report: 报告数据结构。
        metrics_summary: 指标摘要数据结构。
        duration: 评估持续时间（秒）。

    Returns:
        格式化的报告字符串。
    """
    report_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "reports")
    os.makedirs(report_dir, exist_ok=True)

    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    report_path = os.path.join(report_dir, f"evaluation_report_{timestamp}.json")

    with open(report_path, "w") as f:
        json.dump(report, f, indent=2)

    # Add the report path to the report data for reference
    report["generate_report_path"] = report_path

    logger.info("Evaluation report generated", report_path=report_path)
    return report_path
